<template>
    <div>
        <el-container class="app-container">
            <el-header class="app-header">
                <h1>PDF OCR文档处理系统</h1>
            </el-header>
            <el-main class="main-container">
                <div class="content-container">
                    <el-steps
                        :active="currentStep"
                        finish-status="success"
                        class="mb-20"
                    >
                        <el-step
                            title="上传文件"
                            description="上传PDF或ZIP文件"
                        ></el-step>
                        <el-step
                            title="OCR处理"
                            description="处理PDF文件"
                        ></el-step>
                        <el-step
                            title="选择提示词"
                            description="选择处理方式"
                        ></el-step>
                        <el-step
                            title="下载结果"
                            description="获取处理结果"
                        ></el-step>
                    </el-steps>

                    <!-- 上传文件卡片 -->
                    <el-card v-if="currentStep === 0" class="mb-20">
                        <template #header>
                            <div class="card-header">
                                <h2>上传PDF文件</h2>
                            </div>
                        </template>
                        <el-upload
                            class="upload-container"
                            drag
                            action="/api/upload"
                            :on-success="handleUploadSuccess"
                            :on-error="handleUploadError"
                            :before-upload="beforeUpload"
                            :file-list="fileList"
                            :auto-upload="true"
                            :limit="1"
                        >
                            <el-icon class="el-icon--upload"
                                ><upload-filled
                            /></el-icon>
                            <div class="el-upload__text">
                                拖拽文件到此处或 <em>点击上传</em>
                            </div>
                            <template #tip>
                                <div class="el-upload__tip">
                                    请上传PDF或ZIP文件, 文件大小不超过100MB
                                </div>
                            </template>
                        </el-upload>
                        <div v-if="uploading" class="mt-20 text-center">
                            <el-progress
                                :percentage="uploadProgress"
                                :indeterminate="true"
                            ></el-progress>
                            <p>上传中，请稍候...</p>
                        </div>

                        <!-- 上传成功后显示文件列表 -->
                        <div v-if="uploadResponse && !uploading" class="mt-20">
                            <el-alert
                                title="文件上传成功"
                                type="success"
                                :closable="false"
                                class="mb-20"
                            >
                            </el-alert>

                            <div class="file-list">
                                <h3>已上传文件</h3>
                                <el-table
                                    :data="fileList"
                                    stripe
                                    style="width: 100%"
                                >
                                    <el-table-column
                                        prop="filename"
                                        label="文件名"
                                    ></el-table-column>
                                    <el-table-column label="操作" width="180">
                                        <template #default="scope">
                                            <el-button
                                                type="danger"
                                                size="small"
                                                @click="
                                                    removeFile(
                                                        scope.row.filename
                                                    )
                                                "
                                            >
                                                删除
                                            </el-button>
                                        </template>
                                    </el-table-column>
                                </el-table>

                                <div class="mt-20 text-center">
                                    <el-button
                                        type="primary"
                                        @click="goToNextStep"
                                    >
                                        下一步
                                    </el-button>
                                </div>
                            </div>
                        </div>
                    </el-card>

                    <!-- OCR处理卡片 -->
                    <el-card v-if="currentStep === 1" class="mb-20">
                        <template #header>
                            <div class="card-header">
                                <h2>OCR处理</h2>
                            </div>
                        </template>
                        <div v-if="uploadResponse">
                            <el-alert
                                title="文件上传成功"
                                type="success"
                                :closable="false"
                                class="mb-20"
                            >
                                <template #default>
                                    已上传文件:
                                    <strong>{{ selectedFile }}</strong>
                                </template>
                            </el-alert>

                            <el-button
                                type="primary"
                                @click="handleOcr"
                                :loading="isProcessing"
                            >
                                开始OCR处理
                            </el-button>

                            <div v-if="isProcessing" class="mt-20">
                                <el-progress
                                    :percentage="ocrProgress"
                                    :stroke-width="18"
                                    :format="() => '处理中'"
                                    :indeterminate="ocrProgress < 90"
                                ></el-progress>
                                <div class="processing-tips mt-10">
                                    <p>
                                        <i class="el-icon-loading"></i>
                                        OCR处理中，这可能需要几分钟甚至更长时间，请耐心等待...
                                    </p>
                                    <p class="mt-10 processing-note">
                                        注意：处理较大PDF文件可能需要5-10分钟，期间请不要关闭页面
                                    </p>
                                </div>
                            </div>

                            <!-- OCR处理完成后手动前往下一步 -->
                            <div
                                v-if="ocrResults && !isProcessing"
                                class="mt-20 text-center"
                            >
                                <el-alert
                                    title="OCR处理已完成"
                                    type="success"
                                    :closable="false"
                                    class="mb-20"
                                >
                                </el-alert>
                                <el-button
                                    type="primary"
                                    @click="currentStep = 2"
                                >
                                    前往选择处理方式
                                </el-button>
                            </div>
                        </div>
                    </el-card>

                    <!-- 选择提示词卡片 -->
                    <el-card v-if="currentStep === 2" class="mb-20">
                        <template #header>
                            <div class="card-header">
                                <h2>选择处理方式</h2>
                                <el-button
                                    v-if="ocrResults"
                                    type="text"
                                    @click="downloadOcrText"
                                >
                                    下载OCR文本
                                </el-button>
                            </div>
                        </template>
                        <el-form label-position="top">
                            <el-form-item label="选择处理方式">
                                <el-select
                                    v-model="selectedPrompt"
                                    placeholder="请选择处理方式"
                                    class="w-full"
                                >
                                    <el-option
                                        v-for="prompt in availablePrompts"
                                        :key="prompt.value"
                                        :label="prompt.label"
                                        :value="prompt.value"
                                    />
                                </el-select>
                            </el-form-item>

                            <el-form-item
                                label="目标语言 (仅翻译时需要)"
                                v-if="selectedPrompt === 'translate'"
                            >
                                <el-select
                                    v-model="targetLanguage"
                                    placeholder="请选择目标语言"
                                    class="w-full"
                                >
                                    <el-option label="中文" value="zh" />
                                    <el-option label="英文" value="en" />
                                    <el-option label="日文" value="ja" />
                                    <el-option label="德文" value="de" />
                                    <el-option label="法文" value="fr" />
                                </el-select>
                            </el-form-item>

                            <el-form-item
                                label="总结字数限制"
                                v-if="selectedPrompt === 'summarize'"
                            >
                                <el-input-number
                                    v-model="summaryLength"
                                    :min="100"
                                    :max="2000"
                                    :step="100"
                                    class="w-full"
                                />
                                <div class="el-form-item__tip">
                                    请输入期望的总结字数（100-2000字之间）
                                </div>
                            </el-form-item>

                            <el-form-item>
                                <el-button
                                    type="primary"
                                    @click="handleProcess"
                                    :loading="isProcessing"
                                >
                                    开始处理
                                </el-button>
                            </el-form-item>
                        </el-form>

                        <div v-if="isProcessing" class="mt-20">
                            <el-progress
                                :percentage="processProgress"
                                :indeterminate="true"
                            ></el-progress>
                            <p>文本处理中，请稍候...</p>
                        </div>
                    </el-card>

                    <!-- 下载结果卡片 -->
                    <el-card v-if="currentStep === 3" class="mb-20">
                        <template #header>
                            <div class="card-header">
                                <h2>下载处理结果</h2>
                            </div>
                        </template>
                        <el-result
                            icon="success"
                            title="处理完成!"
                            sub-title="您的文档已成功处理，可以下载结果文件"
                        >
                            <template #extra>
                                <el-button
                                    type="primary"
                                    @click="handleDownload"
                                >
                                    下载 Markdown 文件
                                </el-button>
                                <el-button @click="resetProcess">
                                    处理新文件
                                </el-button>
                            </template>
                        </el-result>
                    </el-card>
                </div>
            </el-main>
            <el-footer class="app-footer">
                <p>PDF OCR文档处理系统 &copy; 2025</p>
            </el-footer>
        </el-container>
    </div>
</template>

<script>
import { ref, onMounted } from "vue";
import axios from "axios";
import { ElMessage, ElMessageBox } from "element-plus";
import { UploadFilled } from "@element-plus/icons-vue";

export default {
    name: "App",
    components: {
        UploadFilled,
    },
    setup() {
        // 状态变量
        const currentStep = ref(0);
        const fileList = ref([]);
        const uploading = ref(false);
        const uploadProgress = ref(0);
        const uploadResponse = ref(null);
        const selectedFile = ref("");
        const processingStatus = ref("");
        const availablePrompts = ref([]);
        const selectedPrompt = ref("");
        const targetLanguage = ref("zh");
        const outputFile = ref("");
        const isProcessing = ref(false);
        const ocrProgress = ref(0);
        const processProgress = ref(0);
        const ocrResults = ref(null);
        const ocrTextContent = ref("");
        const summaryLength = ref(500); // 默认500字

        // 获取可用的提示词
        onMounted(async () => {
            try {
                const response = await axios.get("/api/prompts");
                console.log("获取到的提示词数据:", response.data);

                if (
                    response.data &&
                    response.data.data &&
                    response.data.data.prompts
                ) {
                    // 处理字符串数组格式
                    const promptData = response.data.data.prompts;

                    // 提示词的中文映射
                    const promptNameMap = {
                        translate: "翻译",
                        summarize: "总结",
                        extract_info: "提取信息",
                        qa: "问答",
                        format_markdown: "格式化为Markdown",
                    };

                    // 转换后端返回的字符串数组为前端需要的对象数组
                    availablePrompts.value = promptData.map((name) => {
                        return {
                            label: promptNameMap[name] || name, // 使用中文映射，如果没有则使用原名
                            value: name,
                            description: `使用${
                                promptNameMap[name] || name
                            }处理文本`,
                        };
                    });

                    console.log("转换后的提示词:", availablePrompts.value);

                    if (availablePrompts.value.length > 0) {
                        selectedPrompt.value = availablePrompts.value[0].value;
                        console.log("已选择默认提示词:", selectedPrompt.value);
                    }
                } else {
                    console.error("提示词数据格式不正确:", response.data);
                    ElMessage.warning("提示词数据格式不正确，请联系管理员");
                }
            } catch (error) {
                console.error("获取提示词失败:", error);
                ElMessage.error("获取提示词失败，请刷新页面重试");
            }
        });

        // 上传前检查
        const beforeUpload = (file) => {
            const isPDF = file.type === "application/pdf";
            const isZIP =
                file.type === "application/zip" ||
                file.type === "application/x-zip-compressed";

            if (!isPDF && !isZIP) {
                ElMessage.error("只能上传 PDF 或 ZIP 文件!");
                return false;
            }

            const isLt100M = file.size / 1024 / 1024 < 100;
            if (!isLt100M) {
                ElMessage.error("文件大小不能超过 100MB!");
                return false;
            }

            uploading.value = true;
            return true;
        };

        // 上传成功处理
        const handleUploadSuccess = (response) => {
            uploading.value = false;
            uploadProgress.value = 100;

            // 处理后端返回的不同格式
            if (response && (response.success || response.files)) {
                uploadResponse.value = response;
                // 如果返回的是files数组，使用第一个文件名作为selectedFile
                if (response.files && response.files.length > 0) {
                    selectedFile.value = response.files[0];
                    fileList.value = response.files.map((filename) => ({
                        filename,
                    }));
                } else if (response.filename) {
                    // 兼容旧格式
                    selectedFile.value = response.filename;
                    fileList.value = [{ filename: response.filename }];
                }
                ElMessage.success("文件上传成功");
            } else {
                ElMessage.error(response?.message || "上传失败");
            }
        };

        // 上传失败处理
        const handleUploadError = (error) => {
            uploading.value = false;
            console.error("上传失败:", error);
            ElMessage.error("文件上传失败，请重试");
        };

        // 从文件列表中删除文件
        const removeFile = (filename) => {
            ElMessageBox.confirm("确定要删除该文件吗?", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
            })
                .then(() => {
                    // 可以增加一个调用后端删除文件的API
                    // 这里仅清除前端的状态
                    uploadResponse.value = null;
                    selectedFile.value = "";
                    fileList.value = [];
                    ElMessage.success("文件已删除");
                })
                .catch(() => {
                    // 用户取消操作
                });
        };

        // 从文件列表中直接调用OCR处理
        const handleOcrFromList = (filename) => {
            // 设置当前文件名
            selectedFile.value = filename;

            // 显示处理中状态
            isProcessing.value = true;
            ocrProgress.value = 0;

            // 提示用户OCR可能需要较长时间
            ElMessage({
                message:
                    "OCR处理已开始，大型PDF文件可能需要较长时间，请耐心等待...",
                type: "info",
                duration: 5000,
            });

            // 调用OCR处理
            handleOcr()
                .then(() => {
                    // OCR处理成功后，不需要额外操作，handleOcr会自动跳转到下一步
                    console.log("OCR处理成功，从文件列表中");
                })
                .catch((error) => {
                    console.error("OCR处理失败:", error);
                    isProcessing.value = false;

                    // 不需要再次显示错误消息，因为handleOcr已经显示了
                });
        };

        // 进入下一步
        const goToNextStep = () => {
            currentStep.value = 1; // 进入OCR处理步骤
        };

        // OCR处理
        const handleOcr = () => {
            // 检查是否有选定的文件
            if (!selectedFile.value) {
                ElMessage.error("请先上传文件");
                return Promise.reject("没有选择文件");
            }

            isProcessing.value = true;
            ocrProgress.value = 0;
            const timer = setInterval(() => {
                if (ocrProgress.value < 90) {
                    ocrProgress.value += 5;
                }
            }, 1000);

            // 创建处理请求，使用上传成功后返回的temp_dir
            const requestData = {
                temp_dir: uploadResponse.value?.temp_dir || "",
            };

            console.log("开始OCR处理，请求数据：", requestData);

            // 发送包含请求体的POST请求，设置更长的超时时间
            return axios
                .post(`/api/ocr/${selectedFile.value}`, requestData, {
                    timeout: 300000, // 设置超时时间为5分钟
                })
                .then((response) => {
                    clearInterval(timer);
                    ocrProgress.value = 100;

                    console.log("OCR处理响应：", response.data);

                    if (response.data && response.data.status === "success") {
                        // 保存OCR结果
                        ocrResults.value = response.data;
                        console.log("保存OCR结果：", ocrResults.value);

                        ElMessage.success("OCR处理成功");

                        // 重置处理状态
                        isProcessing.value = false;

                        // 自动前进到下一步
                        currentStep.value = 2;
                        return response.data;
                    } else {
                        throw new Error(
                            response.data?.message || "OCR处理失败"
                        );
                    }
                })
                .catch((error) => {
                    clearInterval(timer);
                    console.error("OCR处理失败：", error);

                    // 检查是否是超时错误
                    if (error.code === "ECONNABORTED") {
                        ElMessage.error(
                            "OCR处理超时，PDF文件可能较大，请稍后重试"
                        );
                    } else {
                        ElMessage.error(error.message || "OCR处理失败");
                    }

                    isProcessing.value = false;
                    ocrProgress.value = 0;
                    throw error;
                });
        };

        // 文本处理
        const handleProcess = async () => {
            if (!selectedFile.value) {
                ElMessage.error("请先上传并OCR处理文件");
                return;
            }

            if (!selectedPrompt.value) {
                ElMessage.error("请选择处理方式");
                return;
            }

            // 如果是翻译但没有选择目标语言
            if (selectedPrompt.value === "translate" && !targetLanguage.value) {
                ElMessage.error("请选择目标语言");
                return;
            }

            // 检查OCR结果
            if (!ocrResults.value?.file_info?.text_path) {
                ElMessage.error("找不到OCR文本文件，请重新进行OCR处理");
                return;
            }

            isProcessing.value = true;
            processProgress.value = 0;

            try {
                // 构建请求参数
                const params = {
                    prompt_type: selectedPrompt.value,
                    temp_dir: uploadResponse.value?.temp_dir || "",
                    source_text: ocrResults.value.file_info.text_path, // 修改为source_text
                    target_language: targetLanguage.value, // 统一使用target_language
                    summary_length: summaryLength.value, // 总结长度参数
                };

                console.log("处理请求参数：", params);

                const response = await axios.post(
                    `/api/process/${selectedFile.value}`,
                    params
                );

                if (response.data && response.data.status === "success") {
                    processProgress.value = 100;
                    outputFile.value = response.data.output_file;
                    ElMessage.success("处理成功");
                    currentStep.value = 3; // 进入下载结果步骤
                } else {
                    ElMessage.error(response.data?.message || "处理失败");
                }
            } catch (error) {
                console.error("处理失败:", error);
                ElMessage.error("处理失败，请重试");
            } finally {
                isProcessing.value = false;
                processProgress.value = 0;
            }
        };

        // 下载结果文件
        const handleDownload = () => {
            if (!selectedFile.value || !outputFile.value) {
                ElMessage.error("没有可下载的文件");
                return;
            }

            console.log("准备下载处理结果文件：", outputFile.value);
            console.log("临时目录：", uploadResponse.value?.temp_dir);

            // 创建下载链接，只使用文件名部分
            const filename = outputFile.value.split("/").pop();
            if (!filename) {
                ElMessage.error("无法获取文件名");
                return;
            }

            if (!uploadResponse.value?.temp_dir) {
                ElMessage.error("无法获取临时目录路径");
                return;
            }

            const downloadUrl = `/api/download/${encodeURIComponent(
                filename
            )}?temp_dir=${encodeURIComponent(
                uploadResponse.value.temp_dir
            )}&type=output`;
            console.log("下载URL：", downloadUrl);

            // 使用axios下载文件
            axios({
                method: "get",
                url: downloadUrl,
                responseType: "blob",
            })
                .then((response) => {
                    const url = window.URL.createObjectURL(
                        new Blob([response.data])
                    );
                    const link = document.createElement("a");
                    link.href = url;
                    link.setAttribute("download", filename);
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                    window.URL.revokeObjectURL(url);
                    ElMessage.success("文件下载成功");
                })
                .catch((error) => {
                    console.error("下载文件时出错：", error);
                    if (error.response) {
                        console.error("错误响应：", error.response.data);
                        ElMessage.error(
                            error.response.data.detail || "下载文件失败，请重试"
                        );
                    } else {
                        ElMessage.error("下载文件失败，请重试");
                    }
                });
        };

        // 重置流程
        const resetProcess = () => {
            ElMessageBox.confirm("确定要重新开始处理新文件吗?", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
            })
                .then(() => {
                    currentStep.value = 0;
                    fileList.value = [];
                    uploading.value = false;
                    uploadProgress.value = 0;
                    uploadResponse.value = null;
                    selectedFile.value = "";
                    processingStatus.value = "";
                    selectedPrompt.value =
                        availablePrompts.value.length > 0
                            ? availablePrompts.value[0].value
                            : "";
                    targetLanguage.value = "zh";
                    outputFile.value = "";
                    isProcessing.value = false;
                    ocrResults.value = null;
                    ocrProgress.value = 0;
                    processProgress.value = 0;
                    ocrTextContent.value = "";
                })
                .catch(() => {
                    // 用户取消操作
                });
        };

        // 下载OCR文本文件
        const downloadOcrText = () => {
            console.log("开始下载OCR文本，当前OCR结果：", ocrResults.value);

            if (!ocrResults.value) {
                ElMessage.warning("请先完成OCR处理");
                return;
            }

            if (
                !ocrResults.value.file_info ||
                !ocrResults.value.file_info.text_path
            ) {
                console.error(
                    "OCR结果中缺少必要的文件信息：",
                    ocrResults.value
                );
                ElMessage.warning("找不到OCR文本文件路径");
                return;
            }

            // 使用text_path中的文件名
            const textFileName = ocrResults.value.file_info.text_path
                .split("/")
                .pop();
            console.log("提取的文本文件名：", textFileName);

            if (!textFileName) {
                ElMessage.warning("无法获取文本文件名");
                return;
            }

            // 创建下载链接，使用text文件名而不是PDF文件名
            const downloadUrl = `/api/download/${textFileName}?temp_dir=${encodeURIComponent(
                uploadResponse.value?.temp_dir || ""
            )}`;
            console.log("下载URL：", downloadUrl);

            // 使用axios下载文件
            axios({
                method: "get",
                url: downloadUrl,
                responseType: "blob",
            })
                .then((response) => {
                    const url = window.URL.createObjectURL(
                        new Blob([response.data])
                    );
                    const link = document.createElement("a");
                    link.href = url;
                    link.setAttribute("download", textFileName);
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                    window.URL.revokeObjectURL(url);
                    ElMessage.success("文件下载成功");
                })
                .catch((error) => {
                    console.error("下载文件时出错：", error);
                    ElMessage.error("下载文件失败，请重试");
                });
        };

        return {
            currentStep,
            fileList,
            uploading,
            uploadProgress,
            uploadResponse,
            selectedFile,
            processingStatus,
            availablePrompts,
            selectedPrompt,
            targetLanguage,
            outputFile,
            isProcessing,
            ocrProgress,
            processProgress,
            ocrResults,
            ocrTextContent,
            summaryLength,
            beforeUpload,
            handleUploadSuccess,
            handleUploadError,
            removeFile,
            handleOcrFromList,
            goToNextStep,
            handleOcr,
            handleProcess,
            handleDownload,
            resetProcess,
            downloadOcrText,
        };
    },
};
</script>

<style>
.app-container {
    min-height: 100vh;
}

.main-container {
    padding: 0;
}

.content-container {
    max-width: 900px;
    margin: 0 auto;
    padding: 0 20px;
}

/* 文件列表样式 */
.file-list {
    margin-top: 20px;
}

.file-list h3 {
    margin: 0 0 10px 0;
    font-size: 16px;
    font-weight: 500;
}

/* 垂直居中相关样式 */
.vertical-center {
    display: flex;
    align-items: center;
}

.el-upload {
    display: flex;
    justify-content: center;
    align-items: center;
}

.el-icon--upload {
    margin: 0 8px 0 0;
}

.el-result__title,
.el-result__subtitle {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    margin: 10px auto;
}

/* 修复步骤组件样式 */
.el-steps {
    display: flex;
    justify-content: space-between;
    padding: 20px 0;
}

.el-step__head {
    margin-bottom: 8px;
}

.el-step__title,
.el-step__description {
    text-align: center !important;
    line-height: 1.5;
    width: 100% !important;
    padding: 0 !important;
}

.el-step {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    padding: 0 10px !important;
}

.el-step__main {
    text-align: center !important;
    width: 100% !important;
    margin-top: 8px !important;
    position: relative !important;
    top: 20px !important;
}

.el-step__description {
    font-size: 12px !important;
    color: #909399 !important;
    margin-top: 4px !important;
}

.el-step__line {
    top: 15px !important;
}

/* 页面间距和对齐 */
.el-card {
    margin-bottom: 20px;
}

.el-card__body {
    padding: 20px;
}

.el-alert {
    display: flex;
    align-items: center;
}

.app-footer {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    color: #606266;
    background-color: #f5f7fa;
    padding: 20px 0;
}

.app-footer p {
    margin: 0;
}

.app-header {
    background-color: #409eff;
    color: white;
    text-align: center;
    line-height: 60px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.app-header h1 {
    margin: 0;
}

.mb-20 {
    margin-bottom: 20px;
}

.mt-20 {
    margin-top: 20px;
}

.text-center {
    text-align: center;
}

.w-full {
    width: 100%;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.card-header h2 {
    margin: 0;
}

.el-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.el-upload__text {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 10px 0;
}

.el-upload__tip {
    display: flex;
    align-items: center;
    justify-content: center;
}

.el-form-item__label {
    display: flex;
    align-items: center;
}

.upload-container {
    width: 100%;
}

.processing-tips {
    background-color: #f2f6fc;
    padding: 15px;
    border-radius: 4px;
    border-left: 4px solid #409eff;
}

.processing-note {
    color: #e6a23c;
    font-size: 14px;
}

/* 增加进度条高度 */
.el-progress--line {
    margin-bottom: 15px;
}

.mt-10 {
    margin-top: 10px;
}

@media (max-width: 768px) {
    .el-steps {
        padding: 0 20px;
    }
}
</style>